package org.jupiter.blog.authentic.controller;

import org.jupiter.blog.authentic.constant.AuthenticConstant;
import org.jupiter.blog.authentic.service.TokenService;
import org.jupiter.blog.authentic.dto.LoginRequestDto;
import org.jupiter.blog.authentic.dto.LoginResponseDto;
import org.jupiter.blog.api.http.JupiterResult;
import org.jupiter.blog.redis.component.SpringRedisRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@RequestMapping("/auth")
public class AuthController {

	private final AuthenticationManager authenticationManager;

	@Autowired
	private TokenService tokenService;

	@Autowired
	private SpringRedisRepository redisRepository;

	public AuthController(AuthenticationManager authenticationManager) {
		this.authenticationManager = authenticationManager;
	}

	@PostMapping("/login")
	public JupiterResult<LoginResponseDto> login(@RequestBody LoginRequestDto request) {
		Authentication authentication = authenticationManager.authenticate(
				new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())
		);

		UserDetails user = (UserDetails) authentication.getPrincipal();
		String token = tokenService.generateToken(user);
		redisRepository.set(AuthenticConstant.AUTH_TOKEN_PREFIX + token, user.getUsername(), 60);
		return JupiterResult.success(new LoginResponseDto(token));
	}

	@PostMapping("/logout")
	public String logout(@RequestHeader(value = "authorization-token", required = false) String authorizationHeader) {
		if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")){
			return "Missing or invalid Authorization header";
		}
		String token = authorizationHeader.substring(7);
		redisRepository.remove(AuthenticConstant.AUTH_TOKEN_PREFIX + token);
		return "Logged out";
	}

	@PostMapping("/force-logout-with-name/{username}")
	public String forceLogoutWithName(@PathVariable String username) {
		redisRepository.remove(AuthenticConstant.AUTH_SESSION_PREFIX + username);
		return "User force logged out: " + username;
	}

	@PostMapping("/force-logout-with-token/{token}")
	public String forceLogoutWithToken(@PathVariable String token) {
		if (token == null || !token.startsWith("Bearer ")){
			return "Missing or invalid Authorization header";
		}
		String tokenKey = token.substring(7);
		redisRepository.remove(AuthenticConstant.AUTH_TOKEN_PREFIX + tokenKey);
		return "User force logged out: " + token;
	}
}

